#!/usr/bin/env python
# coding:utf-8
# Author: mingzhong.huang

import json
import requests
from datetime import datetime
import pandas as pd
from pprint import pprint
from core.logger import logger
from common.utils import get_month_range
from setting import config


class OaPlatform():
    def __init__(self):
        self.url = config.OA_API
        self.username = config.OA_USERNAME
        self.password = config.OA_PASSWORD
        self.user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'
        self.headers = {
            "User-Agent": self.user_agent, "Connection": "keep-alive",
            "Content-Type": "application/json",
        }
        

        
    def rest_token(self):
        """
        重置账号的token。
        """
        try:
            url = self.url + f"/seeyon/rest/token/{self.username}/{self.password}"
            req = requests.get(url=url, headers=self.headers)
            if req.status_code != 200:
                logger.error(f"rest oa token failed")
                return False
            self.headers["token"] = req.text
        except Exception as e:
            logger.error(f"rest oa token error =>{e}")
            return False

        return req.text
    

    def get_member_data(self, member_id):
        """
        根据员工id, 获取员工信息。
        """
        try:
            url = self.url + f"/seeyon/rest/orgMember/{member_id}"
            req = requests.get(url=url, headers=self.headers)
            if req.status_code != 200:
                logger.error(f"get member info failed")
                return False
            result_json = json.loads(req.text)
        except Exception as e:
            logger.error(f"get member info error =>{e}")
            return False
        
        member_data = {
            "name": result_json["name"],
            "email": result_json["emailAddress"],
            "telephone": result_json["telNumber"],
            "department": result_json["orgDepartmentName"],
        }
        return member_data


    def get_flow_ids(self, month: str, template_code: str):
        """
        根据工单的模板id获取, 一个月内所有的流程id。
        """
        try:
            first_day, last_day = get_month_range(month)
            url = self.url + f"/seeyon/rest/flow/FromFinish/{template_code}/{first_day}/{last_day}"
            req = requests.get(url=url, headers=self.headers)
            if req.status_code != 200:
                logger.error(f"get oa flow ids by template_code failed")
                return None, False
            flow_ids = json.loads(req.text)
        except Exception as e:
            logger.error(f"get oa flow ids by template_code error =>{e}")
            return None, False

        return flow_ids, True
    
    
    
    def get_flow_data(self, flow_id):
        """
        根据流程id,获取工单的详细信息
        """
        try:
            url = self.url + f"/seeyon/rest/flow/data/{flow_id}?exportType=0&exportFormat=json"
            req = requests.get(url=url, headers=self.headers)
            if req.status_code != 200:
                logger.error(f"get flow:{flow_id} data failed")
                return False
            flow_data = json.loads(req.text)
        except Exception as e:
            logger.error(f"get flow:{flow_id} data error =>{e}")
            return False

        return flow_data
    
    
    
    
    
    
    
    def update_asset_info_from_flow_data(self, flow_data: dict, asset_info: dict):
        """
        从工单
        """
        # 从固定字段中获取信息
        for value in flow_data['formContent']['values']:
            if value["displayName"] == "申请人":
                # 获取工单的人员组织信息
                member_data = self.get_member_data(value["value"])
                if not member_data:
                    logger.error(f"{asset_info['flow_id']} get member data failed")
                    return False
                
                asset_info["name"] = member_data["name"]
                asset_info["department"] = member_data["department"]
                continue
            
            if value["displayName"] == "费用成本":
                asset_info["price"] = value["value"]
                continue
            
            if value["displayName"] == "申请类型":
                asset_info["application_type"] = value["value"]
                continue
            
            if value["displayName"] == "申请原因":
                asset_info["comment"] = value["value"]
                continue
        
        # 历史原因，有些工单特殊处理
        if asset_info["flow_id"] == "-3672100481993457377":
            asset_info["price"] = "-382"
            
        # 更新 application_type 字段
        if asset_info["application_type"] == "变更":
            if asset_info["price"].startswith("-"):
                asset_info["application_type"] = "降配"
            else:
                asset_info["application_type"] = "升级"
        elif asset_info["application_type"] == "删除/回收":
            asset_info["application_type"] = "回收"
        
        # 拿到从属性数据
        for subordinateForm in flow_data['formContent']['subordinateForms']:
            if subordinateForm["values"][0]["record"][1]["value"]:
                sub_values = subordinateForm["values"]
                break
        else:
            logger.error(f"{asset_info['flow_id']} get sub values failed")
            return False
        
        # 获取动态字段资产信息
        for sub_value in sub_values:
            for record in sub_value["record"]:
                if record["displayName"] in ["实例名称", "回收PolarDB名称", "新增MongoDB名称", "资源名称", "回收实例名称", "新增实例名称", "变更实例名称","选择变更实例名称", "选择回收实例名称", "集群名称"]:
                    asset_info["asset_names"].append(record["value"])
                    continue
                
                if record["displayName"] in ["所属账号", "", "回收PolarDB所属账号", "新增所属账号", "回收所属账号", "新增所属账号", "回收所属账号", "变更所属账号"]:
                    asset_info["cloud_platform"] = record["value"].split("-")[0]
                    asset_info["cloud_account"] = record["value"].split("-")[1] if len(record["value"].split("-")) == 2 else record["value"]
                    continue
            
        if "" in asset_info.values():
            logger.error(f"asset_tmp has empty field values=> {asset_info}")
            # return False

            
        return True
                
            
                
            
    
    
    def get_asset_infos_for_comm(self, month: str):
        """
        获取服务器相关的工单数据, oa平台服务器模板id: Y2023072509
        """
        try:
            oa_infos = [
                {
                    "template_code": "Y2023072509",
                    "type": "ECS"
                },
                {
                    "template_code": "Y2023072507",
                    "type": "RDS"
                },
                {
                    "template_code": "Y2023072508",
                    "type": "Redis"
                },
                {
                    "template_code": "Y2023072501",
                    "type": "HBase"
                },
                {
                    "template_code": "Y2023072506",
                    "type": "云特殊资源"
                },
                {
                    "template_code": "Y2023072502",
                    "type": "MongoDB"
                },
                {
                    "template_code": "Y2023072503",
                    "type": "PolarDB"
                }
            ]
            asset_infos = []
            for oa_info in oa_infos:
                # 获取工单的流程id
                flow_ids, result = self.get_flow_ids(month, oa_info['template_code'])
                if not result:
                    logger.error(f"{oa_info['type']} get flow ids failed")
                    return False
                
                for flow_id in flow_ids:
                    # 根据流程id，获取一个工单的详细信息
                    flow_data = self.get_flow_data(flow_id)
                    if not flow_data:
                        logger.error(f"{flow_id} get flow data failed")
                        return False
                    
                    # 初始化数据结构
                    asset_info = {
                        "name": "",
                        "department": "",
                        "application_type": "",
                        "create_time": flow_data["flowCreateTime"],
                        "close_month": month,
                        "price": "",
                        "flow_id": str(flow_id),
                        "flow_title": flow_data["flowTitle"],
                        "cloud_platform": "",
                        "cloud_account": "",
                        "asset_names": [],
                        "asset_type": oa_info['type'],
                        "comment": ""
                    }
                                      
                    # 根据工单详细信息获得资产信息
                    result = self.update_asset_info_from_flow_data(flow_data, asset_info)
                    if not result:
                        logger.error(f"{asset_info['flow_id']} update asset_info from flow_data failed")
                        return False
                    
                    asset_infos.append(asset_info)
        except Exception as e:
            logger.error(f"get comm asset infos error =>{e}")
            return False

        logger.info(f"get comm asset infos success")
        return asset_infos


    
    def get_asset_infos(self, month: str):
        # 重置下token，防止token过期
        self.rest_token()
        
        # 获取通用的工单信息
        comm_asset_infos = self.get_asset_infos_for_comm(month)
        if not comm_asset_infos:
            logger.error(f"get asset infos for comm failed")
            return False
        
        # # 获取rds的工单信息
        # rds_asset_infos = self.get_asset_infos_for_rds(month)
        # if not rds_asset_infos:
        #     logger.error(f"get asset infos for rds failed")
        #     return False
        
        
        asset_infos = comm_asset_infos 
        return asset_infos
        



def main():
    oa_platform = OaPlatform()
    # oa_platform.rest_token()
    # oa_platform.get_flow_ids("2023-07", "Y2023072509")
    # oa_platform.get_work_order_for_ecs("2023-07")
    # oa_platform.get_asset_infos_for_rds("2023-07")
    asset_infos = oa_platform.get_asset_infos("2023-09")
    
    
    return True

        


if __name__ == "__main__":
    main()



